namespace SubhadraSolutions.Sharp.Logging.Common
{
    using SubhadraSolutions.Sharp.Logging.Contracts;
    using SubhadraSolutions.Sharp.Utils;
    using SubhadraSolutions.Sharp.Utils.Collections.Concurrent;
    using System;
    using System.Threading;

    public class LogBuffer : AbstractInitializableAndDisposable, ILogBuffer
    {
        #region Fields

        private ConcurrentStore<LogStoreItem> _logBuffer;

        #endregion Fields

        #region Constructors

        public LogBuffer()
        {
            FlushingThreadPriority = ThreadPriority.Normal;
            BufferSize = 1;
            PeriodicFlushInterval = 2000;
            MaxWaitTime = -1;
        }

        #endregion Constructors

        #region Events

        public event EventHandler<StoreFlushEventArgs<LogStoreItem>> OnStoreFlush;

        #endregion Events

        #region Properties

        public int BufferSize
        {
            get;
            set;
        }

        public ThreadPriority FlushingThreadPriority
        {
            get;
            set;
        }

        public long MaxWaitTime
        {
            get;
            set;
        }

        public int PeriodicFlushInterval
        {
            get;
            set;
        }

        #endregion Properties

        #region Methods

        public void ForceFlush()
        {
            _logBuffer.ForceFlush();
        }

        protected override void initializeProtected()
        {
            _logBuffer = new ConcurrentStore<LogStoreItem>(BufferSize, FlushingThreadPriority,
                 PeriodicFlushInterval,
                 MaxWaitTime);
            _logBuffer.OnStoreFlush += _store_OnStoreFlush;
        }

        public bool Write(LogStoreItem item)
        {
            return _logBuffer.Add(item);
        }

        protected override void Dispose(bool disposing)
        {
            _logBuffer.Dispose();
        }

        private void _store_OnStoreFlush(object sender, StoreFlushEventArgs<LogStoreItem> e)
        {
            if (OnStoreFlush != null)
            {
                OnStoreFlush(this, e);
            }
        }

        #endregion Methods
    }
}